package com.mayisoftware.mayioa.business.personal.impl.controller;

import com.mayisoftware.mayioa.business.personal.api.domain.PerConstants;
import com.mayisoftware.mayioa.business.personal.api.domain.PersonalDetail;
import com.mayisoftware.mayioa.business.personal.api.domain.PersonalOV;
import com.mayisoftware.mayioa.business.personal.api.domain.PersonalSign;
import com.mayisoftware.mayioa.business.personal.api.service.IPersonalSignService;
import com.mayisoftware.mayioa.business.plan.api.domain.PlanConfig;
import com.mayisoftware.mayioa.business.plan.api.service.IPlanConfigService;
import com.mayisoftware.mayioa.business.pool.api.domain.PoolConstants;
import com.mayisoftware.mayioa.business.pool.api.domain.PoolMgrInfo;
import com.mayisoftware.mayioa.business.pool.api.service.IPoolManualService;
import com.mayisoftware.mayioa.business.score.api.domain.ScoreInfo;
import com.mayisoftware.mayioa.business.score.api.service.IScoreInfoService;
import com.mayisoftware.mayioa.common.api.constant.Constants;
import com.mayisoftware.mayioa.platform.api.domain.SysDictData;
import com.mayisoftware.mayioa.platform.api.domain.SysUser;
import com.mayisoftware.mayioa.platform.api.service.ISysDictDataService;
import com.mayisoftware.mayioa.platform.impl.util.ShiroUtils;
import com.mayisoftware.mayioa.platform.impl.web.base.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.*;


/**
 * 个人信息浏览控制器
 */
@Controller
@RequestMapping("/personal/overview")
public class PersonalOVController extends BaseController{
    private static final Logger log = LoggerFactory.getLogger(PersonalOVController.class);
    /**
     * 前缀
     */
    private String prefix = "personal/overview";

    /**
     * 字典查询服务
     */
    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 分数查询服务
     */
    @Autowired
    private IScoreInfoService scoreInfoService;

    /**
     * 计划查询服务
     */
    @Autowired
    private IPlanConfigService planConfigService;

    /**
     * 骨干池查询服务
     */
    @Autowired
    private IPoolManualService poolManualService;

    /**
     * 用户报名查询服务
     */
    @Autowired
    private IPersonalSignService personalSignService;

    @RequiresPermissions("personal:overview:view")
    @GetMapping()
    public String user()
    {
        return prefix + "/overview";
    }

    @RequiresPermissions("personal:overview:list")
    @RequestMapping("/list")
    @ResponseBody
    public PersonalOV list()
    {
        PersonalOV result = new PersonalOV();

        SysUser user = ShiroUtils.getSysUser();
        result.setUserId(user.getUserId()+"");
        result.setUserName(user.getUserName());

        //计划 总得分信息
        Map<Integer,PoolMgrInfo> plan_total = new LinkedHashMap<>();

        //设置骨干信息
        setBackboneInfo(result, user,plan_total);

        //查询字典计划类型
        List<SysDictData> dictDataList = sysDictDataService.selectDictDataByType(PerConstants.PLAN_TYPE_DICT_TYPE);

        Map<String,String> plan_typeInfo = new HashMap<>();
        for (SysDictData data:dictDataList) {
            plan_typeInfo.put(data.getDictValue(),data.getDictLabel());
        }

        //调用分数服务查询分数信息
        ScoreInfo queryScoreInfo = new ScoreInfo();
        queryScoreInfo.setScoreUserId(user.getUserId().intValue());
        List<ScoreInfo> scoreInfos = scoreInfoService.selectScoreInfoList(queryScoreInfo);
        List<PersonalDetail> details = new ArrayList<>();

        //计划得分信息
        Map<Integer,List<ScoreInfo>> plan_ScoreInfo = new LinkedHashMap<>();
        for(ScoreInfo info:scoreInfos){
            List<ScoreInfo> tmpScoreInfos= plan_ScoreInfo.get(info.getScorePlanId());
            if (tmpScoreInfos == null){
                tmpScoreInfos = new ArrayList<>();
                tmpScoreInfos.add(info);
                plan_ScoreInfo.put(info.getScorePlanId(),tmpScoreInfos);
            }
            else {
                tmpScoreInfos.add(info);
            }
        }

        for (Map.Entry<Integer,List<ScoreInfo>> plan_info:plan_ScoreInfo.entrySet()){
            Integer planId = plan_info.getKey();

            if (planId == null){
                continue;
            }

            List<ScoreInfo> infos = plan_info.getValue();
            PersonalDetail detail = new PersonalDetail();

            // 计划服务读取
            PlanConfig cfg= planConfigService.selectPlanConfigById(planId.longValue());

            detail.setPlanName(cfg.getPlanCfgName());
            detail.setPlanType(plan_typeInfo.get(cfg.getPlanCfgType()));
            detail.setPassScore(cfg.getPlanCfgPassScore().toPlainString());
            detail.setPlanDesc(cfg.getPlanCfgRemark());

            BigDecimal totalScoreInfo =  plan_total.get(planId).getPoolTotalScore();
            detail.setTotalScore(totalScoreInfo);

            Integer rank = plan_total.get(planId).getPoolPlanRank();
            detail.setPlanRank(rank);

            Integer isLastN = plan_total.get(planId).getPoolPlanLastn();
            detail.setIsLastN(isLastN);

            List<String> itemNames = new ArrayList<>();
            List<BigDecimal> itemScores = new ArrayList<>();
            List<String> itemDesces = new ArrayList<>();
            for (ScoreInfo info:infos){
                itemNames.add(info.getPlanItemName());
                itemScores.add(info.getScoreInfo());
                if (StringUtils.isEmpty(info.getPlanItemsReasons())){
                    itemDesces.add("无");
                }
                else {
                    itemDesces.add(info.getPlanItemsReasons());
                }

            }
            detail.setItemScore(itemScores);
            detail.setItemName(itemNames);
            detail.setItemDesc(itemDesces);

            details.add(detail);
        }
        List<PersonalSign> personalSignList = personalSignService.querySignListByUserId(user.getUserId().intValue());
        Integer latestPlanRank = getLatestPlanRank(user.getUserId(), plan_total, personalSignList);
        result.setPlanNum(personalSignList.size());
        result.setLatestPlanRank(latestPlanRank);
        result.setDetails(details);
        return result;
    }

    /**
     * 获取最近的计划的排名
     * @param userid 用户id
     * @param plan_total 骨干池信息
     * @return
     */
    Integer getLatestPlanRank(Long userid, Map<Integer,PoolMgrInfo> plan_total, List<PersonalSign> personalSignList){
        Integer ret=null;
        if(userid == null || plan_total == null || personalSignList == null){
            log.error("参数错误");
            return ret;
        }
        if(plan_total.isEmpty() || personalSignList.isEmpty()){
            log.error("没有计划");
            return ret;
        }
        List<ImmutablePair<Date, Integer>> sortList = new ArrayList<ImmutablePair<Date, Integer>>();
        for(PersonalSign personalSign : personalSignList){
            Integer planId = personalSign.getPerSignPlanId();
            PoolMgrInfo poolMgrInfo = plan_total.get(planId);
            if(poolMgrInfo == null){
                log.error("数据不一致");
                continue;
            }
            Integer rank = poolMgrInfo.getPoolPlanRank();
            Date date = personalSign.getPerSignUpdateTime();
            ImmutablePair<Date, Integer> pair = new ImmutablePair<>(date,rank);

            if(rank != null && date != null){
                sortList.add(pair);
            }
        }
        if(!sortList.isEmpty()){
            //根据日期排序
            sortList.sort((o1, o2) -> (int)(o1.getKey().compareTo(o2.getKey())));
            ret = sortList.get(sortList.size()-1).getValue();
        }
        return ret;
    }

    /**
     * 设置骨干信息
     */
    private void setBackboneInfo(PersonalOV result, SysUser user, Map<Integer,PoolMgrInfo>  plan_score) {
        List<PoolMgrInfo> poolMgrInfos= poolManualService.queryPoolListByUserId(user.getUserId()+"");

        //读取分数信息
        for (PoolMgrInfo mgrInfo:poolMgrInfos) {
            if (mgrInfo.getPoolPlanId() != null){
                plan_score.put(mgrInfo.getPoolPlanId(),mgrInfo);
            }
        }

        boolean isBackbone= false;

        //是骨干处理
        for (PoolMgrInfo mgrInfo:poolMgrInfos){

            if (mgrInfo.getPoolIsBackbone().equals(PoolConstants.IS_BACKBONE)){
                isBackbone =true;
                result.setIsBackBone(PoolConstants.IS_BACKBONE_STR);
                if (mgrInfo.getPoolInTime() != null){
                    result.setInTime(Constants.YMD_FMT.format(mgrInfo.getPoolInTime()));
                }
                else {
                    result.setInTime("");
                }

                result.setOutTime("");
                result.setInType(mgrInfo.getPoolCreateType() ==0? PoolConstants.IN_TYPE_STR_AUTO:PoolConstants.IN_TYPE_STR_MUL);
                result.setOutType("");
                break;
            }
        }

        boolean hasMul = false;
        Date outDate = null;

        //不是骨干处理
        for (PoolMgrInfo mgrInfo:poolMgrInfos) {
            if (mgrInfo.getPoolCreateType() == PoolConstants.CREATE_TYPE_MUL) {
                hasMul = true;
                outDate = mgrInfo.getPoolOutTime();
                break;
            }
            else {
                outDate=mgrInfo.getPoolOutTime();
            }
        }

        if(!isBackbone){
            result.setIsBackBone(PoolConstants.NOT_BACKBONE_STR);
            result.setInType("");
            result.setInTime("");
            if (hasMul){
                result.setOutType(PoolConstants.OUT_TYPE_STR_MUL);
            }
            else {
                result.setOutType(PoolConstants.OUT_TYPE_STR_AUTO);
            }

            if (outDate != null){
                result.setOutTime(Constants.YMD_FMT.format(outDate));
            }

        }
    }


}
